package com.jichangxiu.common.context;

import com.jichangxiu.common.constant.Constants;
import com.jichangxiu.common.entity.bo.JcxContextEntity;
import com.jichangxiu.common.entity.bo.Record;
import com.jichangxiu.common.entity.rule.PostRule;
import com.jichangxiu.common.entity.rule.PowerRule;
import com.jichangxiu.common.entity.rule.RoleRule;
import com.jichangxiu.common.utils.ObjUtils;

import java.util.List;
import java.util.stream.Collectors;

public class JcxContext {

    private JcxContext() {
    }

    private static final ThreadLocal<JcxContextEntity> JCX_CONTEXT_ENTITY_THREAD_LOCAL = ThreadLocal.withInitial(JcxContextEntity::new);

    public static void setJcxContextEntity(JcxContextEntity jcxContextEntity) {
        JCX_CONTEXT_ENTITY_THREAD_LOCAL.set(jcxContextEntity);
    }

    public static String getTenantId() {
        return JCX_CONTEXT_ENTITY_THREAD_LOCAL.get().getTenantId();
    }

    public static String getTenantName() {
        return JCX_CONTEXT_ENTITY_THREAD_LOCAL.get().getTenantName();
    }

    public static String getTenantSource() {
        return JCX_CONTEXT_ENTITY_THREAD_LOCAL.get().getTenantSource();
    }

    public static String getDeptId() {
        return JCX_CONTEXT_ENTITY_THREAD_LOCAL.get().getDeptId();
    }

    public static String getDeptName() {
        return JCX_CONTEXT_ENTITY_THREAD_LOCAL.get().getDeptName();
    }

    public static String getUserId() {
        return JCX_CONTEXT_ENTITY_THREAD_LOCAL.get().getUserId();
    }

    public static String getUserCode() {
        return JCX_CONTEXT_ENTITY_THREAD_LOCAL.get().getUserCode();
    }

    public static String getUserName() {
        return JCX_CONTEXT_ENTITY_THREAD_LOCAL.get().getUserName();
    }

    public static String getJti() {
        return JCX_CONTEXT_ENTITY_THREAD_LOCAL.get().getJti();
    }

    public static String getJwt() {
        return JCX_CONTEXT_ENTITY_THREAD_LOCAL.get().getJwt();
    }

    public static List<PostRule> getPostRuleList() {
        return JCX_CONTEXT_ENTITY_THREAD_LOCAL.get().getPostRuleList();
    }

    public static List<String> getPostCodeList() {
        return JCX_CONTEXT_ENTITY_THREAD_LOCAL.get().getPostRuleList().stream().map(PostRule::getPostCode).collect(Collectors.toList());
    }

    public static List<String> getPostScopeList() {
        return JCX_CONTEXT_ENTITY_THREAD_LOCAL.get().getPostRuleList().stream().map(PostRule::getPostScope).collect(Collectors.toList());
    }

    public static List<RoleRule> getRoleRuleList() {
        return JCX_CONTEXT_ENTITY_THREAD_LOCAL.get().getRoleRuleList();
    }

    public static List<String> getRoleCodeList() {
        return JCX_CONTEXT_ENTITY_THREAD_LOCAL.get().getRoleRuleList().stream().map(RoleRule::getRoleCode).collect(Collectors.toList());
    }

    public static List<PowerRule> getPowerRuleList() {
        return JCX_CONTEXT_ENTITY_THREAD_LOCAL.get().getPowerRuleList();
    }

    public static List<String> getPowerCodeList() {
        return JCX_CONTEXT_ENTITY_THREAD_LOCAL.get().getPowerRuleList().stream().map(PowerRule::getPowerCode).collect(Collectors.toList());
    }

    public static JcxContextEntity getJcxContextEntity() {
        return JCX_CONTEXT_ENTITY_THREAD_LOCAL.get();
    }

    public static void clearJcxContextEntity(JcxContextEntity jcxContextEntity) {
        JCX_CONTEXT_ENTITY_THREAD_LOCAL.remove();
    }

    private static class SecurityUserHolder {

        private static final ThreadLocal<Object> SECURITY_USER_THREAD_LOCAL = new ThreadLocal<>();

        public static <SU> void setSecurityUser(SU securityUser) {
            SecurityUserHolder.SECURITY_USER_THREAD_LOCAL.set(securityUser);
        }

        @SuppressWarnings("unchecked")
        public static <SU> SU getSecurityUser() {
            return (SU) SecurityUserHolder.SECURITY_USER_THREAD_LOCAL.get();
        }

        public static void clearSecurityUser() {
            SecurityUserHolder.SECURITY_USER_THREAD_LOCAL.remove();
        }

    }

    public static <SU> void setSecurityUser(SU securityUser) {
        SecurityUserHolder.setSecurityUser(securityUser);
    }

    public static <SU> SU getSecurityUser(Class<SU> cs) {
        return ObjUtils.getValueByClass(SecurityUserHolder.getSecurityUser(), cs);
    }

    public static Record getSecurityUser() {
        return Record.getRecord(SecurityUserHolder.getSecurityUser());
    }

    public static void clearSecurityUser() {
        SecurityUserHolder.clearSecurityUser();
    }

    private static final ThreadLocal<String> SOURCE_CODE_THREAD_LOCAL = ThreadLocal.withInitial(() -> Constants.DEFAULT_DATA_SOURCE);

    public static String getSourceCode() {
        return SOURCE_CODE_THREAD_LOCAL.get();
    }

    public static void setSourceCode(String sourceCode) {
        SOURCE_CODE_THREAD_LOCAL.set(sourceCode);
    }

    public static void clearSourceCode() {
        SOURCE_CODE_THREAD_LOCAL.remove();
    }

    private static final ThreadLocal<Boolean> ENABLED_TENANT_THREAD_LOCAL = ThreadLocal.withInitial(() -> null);

    public static Boolean getEnabledTenant() {
        return ENABLED_TENANT_THREAD_LOCAL.get();
    }

    public static void setEnabledTenant(boolean isIgnore) {
        ENABLED_TENANT_THREAD_LOCAL.set(isIgnore);
    }

    public static void clearEnabledTenant() {
        ENABLED_TENANT_THREAD_LOCAL.remove();
    }

}
